/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.ddtroops.web.actionbeans;


import cz.muni.fi.pa165.ddtroops.dto.HeroDTO;
import cz.muni.fi.pa165.ddtroops.dto.RaceDTO;
import cz.muni.fi.pa165.ddtroops.dto.SkillDTO;
import cz.muni.fi.pa165.ddtroops.dto.SquadDTO;
import cz.muni.fi.pa165.ddtroops.dto.UserDTO;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.HeroService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.RaceService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.SkillService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.SquadService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.UserService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.apache.log4j.Logger;

/**
 *
 * @author Erik
 */
@UrlBinding("/heroes/{$event}/{hero.id}")
public class HeroActionBean implements ActionBean {
    static Logger log = Logger.getLogger(HeroActionBean.class);

    private ActionBeanContext context;
    @SpringBean(value = "heroWebService")
    private HeroService service;
    @SpringBean(value = "raceWebService")
    private RaceService raceService;
    @SpringBean(value = "skillWebService")
    private SkillService skillService;
    @SpringBean(value = "squadWebService")
    private SquadService squadService;
    @SpringBean(value="userWebService")
    private UserService userService;
    private RaceDTO race;

    public List<SkillDTO> getSkillsOfProffessionAndXP(String p, Long xp){
        return skillService.getByProfessionAndXp(p, xp);
    }

    public Set<String> getProffessions(){
        Set<String> l = new HashSet<String>();
        for (SkillDTO s : skillService.getAll())
            l.add(s.profession);
        return l;
    }

    public RaceDTO getRace() {
        return race;
    }

    public void setRace(RaceDTO race) {
        this.race = race;
    }


    @Override
    public void setContext(ActionBeanContext abc) {
        this.context = abc;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @DefaultHandler
    public Resolution neco(){
        return new ForwardResolution("/heroes.jsp");
    }

    public Set<HeroDTO> getHeroes(){
        if (getContext().getRequest().isUserInRole("ROLE_SUPERVISOR")) return new HashSet<HeroDTO>(service.getAll());
        else
        {
            UserDTO user = userService.getByName(getContext().getRequest().getRemoteUser());
            List<HeroDTO> heroes = service.getAll();
            Set<HeroDTO> result = new HashSet<HeroDTO>();
            for (HeroDTO s : heroes) {
                if(s.user.name.equals(user.name)) result.add(s);
            }
            return result;
        }
    }
    public SquadDTO getSquad(){
        log.debug("getting squad of hero");
        return squadService.getSquadOfHero(hero);
    }

    private HeroDTO hero = new HeroDTO();
    private List<RaceDTO> races = new ArrayList<RaceDTO>();

    public List<RaceDTO> getRaces(){
        log.debug("getting all races in HeroActionBean");
        return raceService.getAll();
    }

            @ValidateNestedProperties(
        value= {
            @Validate(on={"add", "save"},field="xp", required=true, minvalue=0),
            @Validate(on={"add", "save"},field="biography", required=true),
            @Validate(on={"add", "save"},field="belief", required=true),
            @Validate(on={"add", "save"},field="profession", required=true),
            @Validate(on={"add", "save"},field="strength", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="dexterity", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="constitution", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="intelligence", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="wisdom", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="charisma", required=true, minvalue=0, maxvalue=25),
            @Validate(on={"add", "save"},field="name", required=true)
        }
    )
    public HeroDTO getHero() {
        return hero;
    }

    public void setHero(HeroDTO hero) {
        this.hero = hero;
    }

    public Resolution add(){
        log.debug("adding hero");
        hero.setRace(race);
        List<SkillDTO> skillsForHero = skillService.getByProfessionAndXp(hero.getProfession(), hero.getXp());
        hero.setSkills(skillsForHero);
        hero.user = owner;
        log.debug(hero.race);
        log.debug(hero.user.id);
        service.create(hero);
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution delete(){
        service.delete(hero);
        return new RedirectResolution(this.getClass(), "all");
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"add","edit","save"})
    public void loadRaceFromDb(){
        String ids = context.getRequest().getParameter("hero.race");
        if (ids == null){
            log.debug("hero.race.id je null");
            return;
        }

        race = raceService.getById(Long.parseLong(ids));
    }
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"add","edit","save"})
    public void loadUserFromDb(){
        String id = context.getRequest().getParameter("hero.owner");
        if(id==null){
            log.debug("hero.owner.id je null");
            return;
        }

        owner = userService.getById(Long.parseLong(id));
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save","delete"})
    public void loadHeroFromDb(){
        String ids = context.getRequest().getParameter("hero.getId()");
        if (ids == null) return;
        hero = service.getById(Long.parseLong(ids));
    }

    public Resolution edit(){
        return new ForwardResolution("/heroesEdit.jsp");
    }

    public Resolution save(){
        hero.setRace(race);
        List<SkillDTO> skillsForHero = skillService.getByProfessionAndXp(hero.getProfession(), hero.getXp());
        hero.setSkills(skillsForHero);
        hero.setUser(owner);
        service.update(hero);
        return new RedirectResolution(this.getClass(), "all");
    }

    public UserDTO owner=null;
    public UserDTO getOwner(){
        if(hero.user!=null){
            return userService.getById(hero.user.id);
        }
        if(owner==null){
            this.owner = userService.getByName(getContext().getRequest().getRemoteUser());
        }
        return owner;
    }
    public void setOwner(UserDTO owner){
        this.owner = owner;
    }
}
